import ast
import builtins
import re

from 程序核心代码.mvvm重构.ast节点具体实现.数据类节点.数据类节点 import 数据类ast节点基础模型
from 程序核心代码.mvvm重构.基础定义.节点管理器.自动节点注册表 import 注册节点模型


@注册节点模型(ast.Name)
class 变量节点(数据类ast节点基础模型):
    @classmethod
    def 创建实例(cls, ast节点, 所属节点模型管理器, **kwargs) -> '变量节点':
        变量名 = ast节点.id
        if isinstance(ast节点.ctx, ast.Load) and 所属节点模型管理器:
            for 节点 in reversed(所属节点模型管理器.节点模型列表):
                if isinstance(节点._ast节点, ast.Name) and 节点._ast节点.id == 变量名:
                    #日志记录器.info(f"复用现有的变量节点: {节点模型}, 变量名: {变量名}")
                    return 节点
        # 如果没有找到匹配的节点，则创建一个新实例
        return cls(ast节点, 所属节点模型管理器, **kwargs)

    def __init__(self,ast节点, 所属节点模型管理器,上级节点=None,节点位置=None):

        super().__init__(ast节点, 所属节点模型管理器,节点名称="存储节点",节点位置=节点位置,上级节点=上级节点)
        self.添加接口到节点("数据流", "输入", 接口名称="数据输入", 必须连接=False)
        self.数据类型=None
        self.节点关系检查()
    def 节点数据初始化(self):
        self.参数名称 = "变量名："
        self.操作类型 = self.ast节点.ctx
        self.是否显示 = True
        if self.操作类型 == ast.Store:
            #起始接口.获取属性("节点名称") = "存储节点"
            self.是否显示 = True
        elif self.操作类型 == ast.Load:
            if not self.是否显示:
                self.是否显示 = False
    def 参数值初始函数(self):
        return self.ast节点.id
    def 节点关系检查(self):
        self.节点数据初始化()
        调用流列表=self.条件查找接口("调用流")
        for 调用流接口 in 调用流列表:
            if len(调用流接口.接口连接线模型列表) > 0:
                for 关系 in 调用流接口.接口连接线模型列表:
                    # print("当前关系：",连接线图形项)
                    # print("关系的创建者节点：",连接线图形项.关系创建节点.节点名称)
                    if self ==关系.关系创建节点:
                        调用流接口.从接口删除关系(关系)
                    else:
                        关系.关系创建节点.节点关系检查()
        # print("调用流重新梳理完成")
        self.节点图形项显示名称调整()
        同级节点=self.同级节点检查()
        if 同级节点:
            #不存在同级节点
            self.数据类型检查()
            print("同级节点存在", 同级节点.节点名称)
            return 同级节点
        else:
            同级节点=self.同级节点补充检查()
            if not 同级节点:
                上级容器节点= self.上级容器节点检查()
                if 上级容器节点:
                    print("上级容器节点存在", 上级容器节点.节点名称)
                self.数据类型检查()
                return 上级容器节点
            return None


    def 节点数据解析(self):
        self.节点数据初始化()
        if self.操作类型 == ast.Store:
            #起始接口.获取属性("节点名称") = "存储节点"
            self.是否显示 = True
        elif self.操作类型 == ast.Load:
            if not self.是否显示:
                self.是否显示 = False
            #起始接口.获取属性("节点名称") = "加载节点"
    def 同级检查规则(self,节点):
        if hasattr(节点, "参数值") and 节点.参数值 == self.参数值 and 节点.是否显示 and self.节点ast类型==节点.节点ast类型:
            # 检查节点是否已经数据输入已经使用
            if 节点.查找接口("数据流", "输入"):
                if len(节点.查找接口("数据流", "输入").接口连接线模型列表) > 0:
                    if 节点!=self:
                        return 节点
        return None

    def 同级节点补充检查(self):
        for 节点 in self.所属节点模型管理器.节点模型列表:
            同级数据节点 = self.同级补充检查规则(节点)
            if 同级数据节点 and 同级数据节点 != self:
                return self.主数据节点存在(同级数据节点)
        return None  # 如果没有找到符合条件的节点
    def 同级补充检查规则(self,节点):
        if 节点.节点名称 in {"直接导入ast节点基础模型", "从模块导入ast节点基础模型"}:
            # 确保 _ast节点.names 存在并可迭代
            if not hasattr(节点._ast节点, "names") or not 节点._ast节点.names:
                return None
            # 匹配导入项
            for 导入项 in 节点._ast节点.names:
                if 导入项.asname == self.参数值 or 导入项.name == self.参数值:
                    return 节点
        return None
    def 同级节点检查(self):
        同级数据节点=None
        for 节点 in self.所属节点模型管理器.节点模型列表:
            同级数据节点=self.同级检查规则(节点)
            if 同级数据节点 and 同级数据节点!=self:
                break
        return self.主数据节点存在(同级数据节点)
    def 上级检查规则(self, 节点):
        if hasattr(节点, "参数值") and 节点.参数值 == self.参数值 and 节点.节点ast类型 != ast.Attribute:
            return 节点
        return None
    def 是否为内置(self):
        print("是否为内置")
        if self.所属节点模型管理器.创建者节点 :
            if self.所属节点模型管理器.创建者节点.节点ast类型==ast.FunctionDef:
                for 参数名 in self.所属节点模型管理器.创建者节点.参数名列表:
                    if self.参数值 == 参数名:
                        #删除接口
                        数据输入接口=self.查找接口("数据流", "输入", 接口名称="数据输入")
                        if 数据输入接口:
                            self.删除接口(数据输入接口)

                        return True
        return hasattr(builtins, self.参数值)

    def 数据节点参数值修改(self, 变量名):
        print("数据节点参数值修改")
        self.ast节点.id = 变量名
        #起始接口.节点数据初始化()

        for ast节点 in self.同用处ast节点列表:
            ast节点.id = 变量名
        for ast节点 in self.同步ast节点列表:
            #_ast节点.id = 变量名
            print("同步存储节点节点关系重新处理：",self.同步ast节点列表)
            ast节点.节点关系检查()
            print("节点关系处理完成")
        self.同步ast节点列表=set()
        self.节点关系检查()

    def 参数名检测(self, 新参数 ,重名检查=False):
        # 基于变量名命名规则的检测
        if isinstance(新参数, str):
            # 扩展正则表达式以支持中文字符
            if re.match(r'^[A-Za-z_\u4e00-\u9fff][A-Za-z0-9_\u4e00-\u9fff]*$', 新参数):
                if 重名检查:
                    return self.变量重名检查(新参数)
                return True
            else:
                print("变量名不合法：不符合命名规范")
                return False
        else:
            print("变量名类型不正确，应为字符串")
            return False
    def 变量重名检查(self,新参数):
        变量名表 = self.所属节点模型管理器.ast操作器.获取所有变量名()
        if 新参数 not in 变量名表:
            return True
        else:
            print("变量名重复")
            return False
    def 检查关系是否合法(self,开始接口,结束接口):
        临时接口=None
        if 开始接口.流类型 == "数据流" :
            临时接口=开始接口.节点模型.查找接口("输出", "输出")
        elif 开始接口.流类型 == "调用流" :
            临时接口=开始接口.节点模型.查找接口("数据流", "输出")
        if 临时接口:
            for 关系 in 临时接口.关系列表:
                if 关系.结束接口.节点模型==结束接口.节点模型:
                    print("数据流 和调用流接口不能连接到同一个节点")
                    return False
        return True
    def 节点创建关系(self,开始接口,结束接口):
        print("变量节点创建关系")
        if self.检查关系是否合法(开始接口,结束接口):
            super().节点创建关系(开始接口,结束接口)
        return True


    def 创建独立节点(self):

        n=1
        变量名 = "默认变量名"+str(n)
        while not self.参数名检测(变量名,重名检查=True):
            n+=1
            变量名="默认变量名"+str(n)
        self.ast节点=ast.Name(id=变量名, ctx=ast.Load())
        _变量节点= ast.Expr( self.ast节点)
        self.所属节点模型管理器._ast节点.append(_变量节点)



